package com.iwhalecloud.bss.kite.cucc.web.controller.order;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.net.util.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageInfo;
import com.iwhalecloud.bss.kite.client.api.scene.operate.IOperateSceneProdInstService;
import com.iwhalecloud.bss.kite.client.dto.DataResult;
import com.iwhalecloud.bss.kite.common.constant.ErrorConsts;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteObjectUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IAttachmentService;
import com.iwhalecloud.bss.kite.cucc.client.api.order.IContractService;
import com.iwhalecloud.bss.kite.cucc.client.dto.cust.CuccContextCustDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.inf.req.QryStockAttachMentUrlReqDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.inf.rsp.QryStockAttachMentUrlRspDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.ContractDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.ContractParamDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.ContractRequestDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.ContractSimpleDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.order.DownloadIncludeDataDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.scene.CuccCustInfoDTO;
import com.iwhalecloud.bss.kite.cucc.client.dto.webService.CustContractRsp;
import com.iwhalecloud.bss.kite.cucc.client.vo.scene.ContactServiceVO;
import com.iwhalecloud.bss.kite.cucc.common.constant.LocalKeyConsts;
import com.iwhalecloud.bss.kite.cucc.common.util.StrTools;
import com.iwhalecloud.bss.kite.cucc.manager.scene.service.operate.LocalOperateOfferInstContractRelService;
import com.iwhalecloud.bss.kite.dataservice.cache.DcPublicCache;
import com.iwhalecloud.bss.kite.dataservice.cache.OfferCache;
import com.iwhalecloud.bss.kite.dataservice.entity.spec.Offer;
import com.iwhalecloud.bss.kite.dataservice.util.IdUtils;
import com.iwhalecloud.bss.kite.manager.api.IOperateSceneInstService;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.dto.ContAttachmentDTO;
import com.iwhalecloud.bss.kite.manager.enums.ActionType;
import com.iwhalecloud.bss.kite.manager.enums.InstType;
import com.iwhalecloud.bss.kite.manager.enums.RelType;
import com.iwhalecloud.bss.kite.manager.inst.KiteInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInst;
import com.iwhalecloud.bss.kite.manager.inst.KiteOfferInstContract;
import com.iwhalecloud.bss.kite.manager.inst.KiteProdInst;
import com.iwhalecloud.bss.kite.manager.scene.service.operate.OperateOfferInstContractService;
import com.iwhalecloud.bss.kite.manager.transaction.KiteTransactional;
import com.iwhalecloud.bss.kite.web.context.KiteWebContext;
import com.ztesoft.bss.common.bo.LoginInfo;
import com.ztesoft.bss.common.exception.BssException;
import com.ztesoft.bss.common.util.ContextUtil;
import com.ztesoft.bss.common.util.SpringUtil;
import com.ztesoft.zsmart.core.util.BeanUtil;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

@RestController
@RequestMapping("/contract")
@Api(tags = { "/contract - 合同号" })
public class ContractController {

    @Autowired
    private IContractService contractService;

    @Autowired
    private LocalOperateOfferInstContractRelService operateOfferInstContractRelService;

    @Autowired
    private OperateOfferInstContractService operateOfferInstContractService;

    @Autowired
    private IQuerySceneInstService querySceneInstService;

    @Autowired
    private IOperateSceneInstService iOperateSceneInstService;
    @Autowired
    private IOperateSceneProdInstService operateSceneProdInstService;

    @ApiOperation(value = "合同号查询", notes = "合同号查询")
    @GetMapping
    public DataResult<PageInfo<ContractDTO>> queryContract(String contractNo, String contractName, int pageNum,
                                                           int pageSize) {
        String custId = KiteWebContext.getContext().getCustId();
        PageInfo<ContractDTO> pageInfo = contractService.queryContractByCustId(custId, contractNo, contractName,
            pageNum, pageSize);
        return ErrorConsts.SUCCESS.getResult(pageInfo);
    }

    @KiteTransactional
    @ApiOperation(value = "受理单上传", notes = "受理单上传")
    @PostMapping
    public DataResult<ContractSimpleDTO> createAndUploadContract(@RequestBody ContractParamDTO contractParam) {
        CuccContextCustDTO custDTO = (CuccContextCustDTO) KiteWebContext.getContext().getCust();
        ContractRequestDTO contractRequestDTO = new ContractRequestDTO();
        BeanUtil.copy(contractParam, contractRequestDTO);
        String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();
        // _transNewCustDTO对象为过户时，存的过户后的新客户信息
        Map<String, Object> extParameter = querySceneInstService.getExtParameter(sceneInstId);
        Object newCust = extParameter.get(sceneInstId + "_transNewCustDTO");
        CuccCustInfoDTO newCustDto = Objects.nonNull(newCust) ? (CuccCustInfoDTO) newCust : null;
        if (Objects.nonNull(newCustDto)) {
            contractRequestDTO.setCustId(newCustDto.getCustId());
            contractRequestDTO.setCustCode(newCustDto.getGroupId());
            contractRequestDTO.setCustName(newCustDto.getCustName());
            contractRequestDTO.setContractName(newCustDto.getCustName());
            if (KiteStringUtils.isEmpty(newCustDto.getCustClassType())) {
                contractRequestDTO.setCustType(newCustDto.getCustType());
            } else {
                contractRequestDTO.setCustType(newCustDto.getCustClassType());
            }
        }
        else {
            contractRequestDTO.setCustId(custDTO.getCustId());
            contractRequestDTO.setCustCode(custDTO.getGroupId());
            contractRequestDTO.setCustName(custDTO.getCustName());
            contractRequestDTO.setContractName(custDTO.getCustName());
            if (KiteStringUtils.isEmpty(custDTO.getCustClassType())) {
                contractRequestDTO.setCustType(custDTO.getCustType());
            } else {
                contractRequestDTO.setCustType(custDTO.getCustClassType());
            }
        }
        //TODO此处支持其他销售品时需要修改，offerInstID前端传
        String offerInstId = contractParam.getOfferInstId();
        if (KiteStringUtils.isEmpty(offerInstId)) {
            offerInstId = querySceneInstService.getMainOfferInst(KiteWebContext.getContext().getCurrentSceneInstId()).getOfferInstId();
        }
        if (KiteStringUtils.isEmpty(contractParam.getCataId())) {
            KiteOfferInst offerInst = querySceneInstService.getOfferInst(custDTO.getCustId(), offerInstId);
            contractParam.setCataId(Optional.ofNullable(OfferCache.get(offerInst.getSpecId())).map(Offer::getCateId).orElse(""));
        }
        String contractType = DcPublicCache.getPCode("20201112003", contractParam.getCataId());
        if (KiteStringUtils.isEmpty(contractType)&&KiteStringUtils.isEmpty(contractRequestDTO.getContractType())) {
            contractType = LocalKeyConsts.DEFAULT_CONTRACT_TYPE;
            //ErrorConsts.BUSI_COMMON_ERROR.throwOut(I18nUtil.getMessage("CONTRACT_TPYE_IS_EMPTY"));
            contractRequestDTO.setContractType(contractType);
        }


        ContractSimpleDTO contractSimpleDTO = contractService.createAndUploadContract(contractRequestDTO);
        //合同号上传标记
        if (KiteStringUtils.isNotEmpty(contractSimpleDTO.getContractNo())){
            iOperateSceneInstService.putExtParameter(sceneInstId, "isCreateAndUploadContract", "T");
        }
        contractSimpleDTO.setFileId(contractParam.getAccessoryId());
        contractSimpleDTO.setFileName(contractParam.getAccessoryName());

        KiteOfferInstContract offerInstContractRel = new KiteOfferInstContract();
        offerInstContractRel.setInstId(IdUtils.generateInstId(InstType.PROD_INST_ACCT));
        offerInstContractRel.setOfferInstId(offerInstId);
        //合同批次号
        offerInstContractRel.setContractBatchId(contractSimpleDTO.getContractId());
        //合同编号
        offerInstContractRel.setContractNo(contractSimpleDTO.getContractNo());
        offerInstContractRel.setContractName(contractSimpleDTO.getContractName());
        offerInstContractRel.setContractUrl(contractParam.getAccessoryId());
        offerInstContractRel.setInstType(InstType.OFFER_INST_CONTRACT);
        if(KiteStringUtils.isEmpty(contractParam.getContractType())){
            offerInstContractRel.setContractType(LocalKeyConsts.CONTRACT_TYPE_02);
        }else{
            offerInstContractRel.setContractType(contractParam.getContractType());
        }
        List<ContAttachmentDTO> attachment=new ArrayList<ContAttachmentDTO>();
        if(!KiteObjectUtils.isEmpty(contractSimpleDTO.getAttachments())){
            String oldattachment = JSONObject.toJSONString(contractSimpleDTO.getAttachments());
            attachment=JSONObject.parseArray(oldattachment, ContAttachmentDTO.class);
            offerInstContractRel.setAttachments(attachment);
        }

        KiteOfferInst offerInst = querySceneInstService.getOfferInst(KiteWebContext.getContext().getCustId(), offerInstId);
        if (KiteObjectUtils.isEmpty(offerInst)) {
            ErrorConsts.OFFER_INST_NOT_EXIST.throwOut(offerInstId, KiteWebContext.getContext().getCustId());
        }

        List<KiteOfferInstContract> contracts = querySceneInstService.listOfferInstContracts(KiteWebContext.getContext().getCustId(), offerInstId);
        if (!KiteListUtils.isEmpty(contracts)) {
            contracts.forEach(contract -> {
                if (!KiteStringUtils.equals(contract.getActionType().name(), ActionType.X.name()) && !KiteStringUtils.equals(contract.getActionType().name(), ActionType.D.name())) {
                    operateOfferInstContractRelService.deleteOfferInstContractRel(KiteWebContext.getContext().getCurrentSceneInstId(), contractParam.getOfferInstId(), InstType.MAIN_OFFER_INST, contract.getOfferObjInstRelId());
                }
            });
        }
        if(KiteStringUtils.equalsAny(contractParam.getCataId(), "2000991","2000993")){//5g个性化需求(选择合同后-合同编码回显到产品属性上)
            List<KiteProdInst> prodInsts = querySceneInstService.listProdInstsFromOfferInst(custDTO.getCustId(), offerInstId);
            contractSimpleDTO.setContractecho("contractNo");
            operateSceneProdInstService.updateProdInstAttr(sceneInstId, prodInsts.get(0).getProdInstId(), "200003088", contractSimpleDTO.getContractNo(),contractSimpleDTO.getContractNo(), custDTO.getCustId(), ContextUtil.getUserId().toString(), null);

        }
        // 没有账户明细关系，明细ID传销售品id
        String offerId = Optional.ofNullable(OfferCache.get(offerInst.getOfferId())).map(Offer::getOfferId).orElse("");

        String offerInstContractRelId = operateOfferInstContractService.addOfferInstContract(KiteWebContext.getContext().getCurrentSceneInstId(), offerInstContractRel, offerInstId, RelType.OFFER_OBJ_REL_TYPE_190000, ActionType.A, KeyConsts.OFFER_CONTRACT_ROLE, offerId);
        contractSimpleDTO.setOfferInstContractRelId(offerInstContractRelId);
        //operateOfferInstContractRelService.addOfferInstContractRel(KiteWebContext.getContext().getCurrentSceneInstId(), offerInstId,
        //    InstType.MAIN_OFFER_INST, contractSimpleDTO.getContractId(), contractSimpleDTO.getContractNo(), contractSimpleDTO.getContractName(), contractParam.getAccessoryId());

        return ErrorConsts.SUCCESS.getResult(contractSimpleDTO);
    }

    @ApiOperation(value = "受理单下载 返回下载路径", notes = "受理单下载、返回下载路径")
    @GetMapping("downloadIncludeData")
    public DataResult<Map<String, Object>> downloadIncludeData(String goodsCode, String categroyCode, HttpServletResponse response) {
        String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();
        String staffId = ContextUtil.getLoginInfo().getStaffId() + "";
        String orgId = ContextUtil.getLoginInfo().getOrgInfo().getOrgId() + "";
        CuccContextCustDTO custDto = (CuccContextCustDTO) KiteWebContext.getContext().getCust();
        // 设置文件名
        //ServletOutputStream out = null;
        DownloadIncludeDataDTO downloadIncludeData = null;
        try {
        	downloadIncludeData = contractService.downloadIncludeData(goodsCode, categroyCode,
                    sceneInstId, staffId, orgId, custDto);
        }
        catch (BssException ex) {
        	return ErrorConsts.BUSI_COMMON_ERROR.getResult(null, ex.getFailMsg());
        }
        if (downloadIncludeData != null && downloadIncludeData.getTempData() != null) {
        	Map<String, Object> dataMap = new HashMap<String, Object>();
            dataMap.put("fileData", Base64.decodeBase64(downloadIncludeData.getTempData()));
            dataMap.put("fileName", downloadIncludeData.getTempName());
            return ErrorConsts.SUCCESS.getResult(dataMap);
        }
        return ErrorConsts.BUSI_COMMON_ERROR.getResult(null, "受理单下载失败，没有配置受理单模板");
    }

    @KiteTransactional
    @ApiOperation(value = "存量合同-点击确定", notes = "存量合同-点击确定")
    @PostMapping("/clickConfirm")
    public DataResult<List<KiteOfferInstContract>> clickConfirm(@RequestBody ContactServiceVO contactServiceVO) {
        List<String> offerInstIdList = KiteListUtils.strToList(",", contactServiceVO.getOfferInstId());
        List<KiteOfferInstContract> kiteOfferInstContractList= new ArrayList<>();
        QryStockAttachMentUrlReqDTO qryStockAttachMentUrlReq = new QryStockAttachMentUrlReqDTO();
        LoginInfo loginInfo = ContextUtil.getLoginInfo();
        qryStockAttachMentUrlReq.setProvinceCode(loginInfo.getUserInfo().getPostProvinceNbr());
        qryStockAttachMentUrlReq.setEsbFileName(contactServiceVO.getStockFileUrl());
        String realPath = StrTools.isEmpty(contactServiceVO.getStockFileUrl()) ? contactServiceVO.getAccessoryId() : getUrl(qryStockAttachMentUrlReq);
        offerInstIdList.stream().forEach(t -> {
            if (KiteStringUtils.isEmpty(t)) {
                t = querySceneInstService.getMainOfferInst(KiteWebContext.getContext().getCurrentSceneInstId()).getOfferInstId();
            }

            List<KiteOfferInstContract> contracts = querySceneInstService.listOfferInstContracts(KiteWebContext.getContext().getCustId(), t);
            if (!KiteListUtils.isEmpty(contracts)) {
                for (KiteOfferInstContract contract : contracts) {
                    if (!KiteStringUtils.equals(contract.getActionType().name(), ActionType.X.name()) && !KiteStringUtils.equals(contract.getActionType().name(), ActionType.D.name())) {
                        operateOfferInstContractRelService.deleteOfferInstContractRel(contactServiceVO.getSceneInstId(), t, InstType.MAIN_OFFER_INST, contract.getOfferObjInstRelId());
                    }
                }
            }
            if(!KiteStringUtils.equals("02",contactServiceVO.getContractType())){
                Assert.notEmpty(contactServiceVO.getAttachments(), "合同附件不能为空");
            }
            KiteOfferInstContract kiteOfferInstContract = operateOfferInstContractRelService.addOfferInstContractRel(
                contactServiceVO.getSceneInstId(), t, InstType.MAIN_OFFER_INST, contactServiceVO.getContractId(), contactServiceVO.getContractNo(), contactServiceVO.getContractName(), realPath,contactServiceVO.getContractType(),contactServiceVO.getAttachments());
            // 存量合同上传 不隐藏删除按钮
            kiteOfferInstContract.setChangeShowDelete("T");
            String rootInstId = this.querySceneInstService.getSceneInst(contactServiceVO.getSceneInstId()).getRootInstId();
            InstType instType = this.querySceneInstService.getSceneInst(contactServiceVO.getSceneInstId()).getRootInstType();
            KiteInst kiteInst = this.querySceneInstService.getKiteInst(KiteWebContext.getContext().getCustId(), instType, rootInstId);
            String cateId = OfferCache.get(kiteInst.getSpecId()).getCateId();
            if(KiteStringUtils.equalsAny(cateId, "2000991","2000993")){//5g个性化需求(选择合同后-合同编码回显到产品属性上)
                List<KiteProdInst> prodInsts = querySceneInstService.listProdInstsFromOfferInst(KiteWebContext.getContext().getCustId(), contactServiceVO.getOfferInstId());
                kiteOfferInstContract.setContractecho("contractNo");
                operateSceneProdInstService.updateProdInstAttr(contactServiceVO.getSceneInstId(), prodInsts.get(0).getProdInstId(), "200003088", kiteOfferInstContract.getContractNo(),kiteOfferInstContract.getContractNo(), KiteWebContext.getContext().getCustId(), ContextUtil.getUserId().toString(), null);

            }
            kiteOfferInstContract.setAttachments(contactServiceVO.getAttachments());
            kiteOfferInstContractList.add(kiteOfferInstContract);
        });

        return ErrorConsts.SUCCESS.getResult(kiteOfferInstContractList);
    }

    private String getUrl(QryStockAttachMentUrlReqDTO qryStockAttachMentUrlReq) {
        QryStockAttachMentUrlRspDTO qryStockAttachMentUrlRspDTO = SpringUtil.getBean(IAttachmentService.class)
            .getStockAttachmentUrl(qryStockAttachMentUrlReq);
        if (KiteObjectUtils.isEmpty(qryStockAttachMentUrlRspDTO)) {
            return "";
        }
        return qryStockAttachMentUrlRspDTO.getUrl();
    }

    @ApiOperation(value = "存量合同-查询", notes = "存量合同-查询")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "custId", value = "客户ID", required = false),
        @ApiImplicitParam(name = "contractNo", value = "合同号", required = false),
        @ApiImplicitParam(name = "contractType", value = "合同类型", required = false),
        @ApiImplicitParam(name = "contractName", value = "合同名称", required = false),
        @ApiImplicitParam(name = "pageNum", value = "页码", required = true),
        @ApiImplicitParam(name = "pageSize", value = "每页展示", required = true),
        @ApiImplicitParam(name = "cateId", value = "分类id", required = true),
    })
    @GetMapping("/queryContractInfo")
    public DataResult<PageInfo<CustContractRsp>> queryContractInfo(@RequestParam(required = false) String custId,
                                                                   @RequestParam(required = false) String contractNo, @RequestParam(required = false) String contractName,
                                                                   @RequestParam(required = false) String contractType, @RequestParam(required = false) String isCentreContract,
                                                                   @RequestParam(required = true) int pageNum, @RequestParam(required = true) int pageSize,String cateId) {
        if (KiteStringUtils.isEmpty(custId)) {
            // 增加过户判断场景
            String sceneInstId = KiteWebContext.getContext().getCurrentSceneInstId();
            Map<String, Object> extParameter = querySceneInstService.getExtParameter(sceneInstId);
            Object newCust = extParameter.get(sceneInstId + "_transNewCustDTO");
            CuccCustInfoDTO newCustDto = Objects.nonNull(newCust) ? (CuccCustInfoDTO) newCust : null;
            if (Objects.nonNull(newCustDto)) {
                custId = newCustDto.getCustId();
            }
            else {
                custId = KiteWebContext.getContext().getCustId();
            }
            
        }
        String provinceCode = null;
        if (KiteStringUtils.equals(isCentreContract, "1")) {
            provinceCode = "09";
        }
        else {
            provinceCode = ContextUtil.getLoginInfo().getUserInfo().getPostProvinceNbr();
        }
        PageInfo<CustContractRsp> pageInfo = contractService.queryContractInfoByCustId(custId, contractNo, contractName, contractType,
            provinceCode, pageNum, pageSize,cateId);
        return ErrorConsts.SUCCESS.getResult(pageInfo);
    }

    @ApiOperation(value = "新增合同号", notes = "新增合同号")
    @PostMapping("/addContract")
    public DataResult<PageInfo<ContractDTO>> addContract(String contractNo, String contractName, int pageNum,
                                                         int pageSize) {
        String custId = KiteWebContext.getContext().getCustId();
        PageInfo<ContractDTO> pageInfo = contractService.queryContractByCustId(custId, contractNo, contractName,
            pageNum, pageSize);
        return ErrorConsts.SUCCESS.getResult(pageInfo);
    }

    @KiteTransactional
    @ApiOperation(value = "删除合同", notes = "删除合同")
    @DeleteMapping("/deleteContract")
    public DataResult<Boolean> deleteContract(String sceneInstId, String offerInstId, String offerInstContractRelId) {
        List<String> offerInstIdList = KiteListUtils.strToList(",", offerInstId);
        offerInstIdList.stream().forEach(t -> {
            if (KiteStringUtils.isEmpty(t)) {
                t = querySceneInstService.getMainOfferInst(KiteWebContext.getContext().getCurrentSceneInstId()).getOfferInstId();
            }
            operateOfferInstContractRelService.deleteOfferInstContractRel(sceneInstId, t, InstType.MAIN_OFFER_INST, offerInstContractRelId);
        });


        //删除合同上传标记
        iOperateSceneInstService.putExtParameter(sceneInstId, "isCreateAndUploadContract", "F");
        return ErrorConsts.SUCCESS.getResult(Boolean.TRUE);
    }

    @ApiOperation(value = "存量合同-查询", notes = "存量合同-查询")
    @ApiImplicitParams({
        @ApiImplicitParam(name = "flowId", value = "附件id", required = true)
    })
    @GetMapping("/downloadContract")
    public DataResult<String> downloadContract(@RequestParam(required = true) String flowId) {
        String  contractUrl=DcPublicCache.getCodea("20211231001","contract");
        contractUrl=contractUrl+"?flowId="+flowId+"&userLogin="+"hq-ceshi17";//固定工号下载
        return ErrorConsts.SUCCESS.getResult(contractUrl);
    }
}
